/*
 * Copyright (C) 2013 AndXmppSDK Project <hljdrl@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.drl.xmpp;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.RosterGroup;
import org.jivesoftware.smack.RosterListener;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Presence;

/**
 * 
 * 联系人管理器
 * 
 * @author hljdrl@gmail.com
 */
public final class RosterManager implements RosterListener {

	private Roster mRoster;
	private Map<Integer, String> mDefaultStatusMessages;
	private List<RosterListener> mRemoteRosterListener = null;
	private UserInfo mUserInfo;
	private final TalkClient mTalkClient;

	/**
	 * @param talk
	 */
	public RosterManager(TalkClient talk) {
		mTalkClient = talk;
		mUserInfo = talk.getUserInfo();
		mRoster = mTalkClient.getConnection().getRoster();
		mRemoteRosterListener = new ArrayList<RosterListener>();
		mDefaultStatusMessages = PresenceStatus
				.createDefaultStatusMessagesMap();
	}

	/**
	 * @param user
	 * @param name
	 * @param groups
	 * @return Contact
	 */
	public final Contact addContact(String user, String name, String[] groups) {
		RosterEntry entry = mRoster.getEntry(user);
		try {
			mRoster.createEntry(user, name, groups);
			entry = mRoster.getEntry(user);
		} catch (XMPPException e) {
			e.printStackTrace();
			return null;
		}
		return getContactFromRosterEntry(entry, this);
	}

	/**
	 * @param contact
	 */
	public final void deleteContact(Contact contact) {
		try {
			RosterEntry entry = mRoster.getEntry(contact.getJID());
			if (entry != null) {
				mRoster.removeEntry(entry);
			}
		} catch (XMPPException ex) {
			ex.printStackTrace();
		}
	}

	/**
	 * @param mJid
	 * @return Contact
	 */
	public final Contact getContact(String mJid) {
		if (mRoster.contains(mJid)) {
			return getContactFromRosterEntry(mRoster.getEntry(mJid), this);
		}
		return null;
	}

	/**
	 * @param mJid
	 * @param name
	 */
	public final void setContactName(String mJid, String name) {
		mRoster.getEntry(mJid).setName(name);
	}

	/**
	 * @param mGroupname
	 */
	public final void createGroup(String mGroupname) {
		if (mRoster.getGroup(mGroupname) == null) {
			mRoster.createGroup(mGroupname);
		}
	}

	/**
	 * @param groupName
	 * @param mJid
	 */
	public final void addContactToGroup(String groupName, String mJid) {
		createGroup(groupName);
		RosterGroup group = mRoster.getGroup(groupName);
		try {
			group.addEntry(mRoster.getEntry(mJid));
		} catch (XMPPException xe) {
			xe.printStackTrace();
		}
	}

	/**
	 * @param groupName
	 * @param mJid
	 */
	public final void removeContactFromGroup(String groupName, String mJid) {
		RosterGroup group = mRoster.getGroup(groupName);
		try {
			group.removeEntry(mRoster.getEntry(mJid));
		} catch (XMPPException xe) {
			xe.printStackTrace();
		}

	}

	/**
	 * @return
	 */
	public List<Contact> getContactList() {
		Collection<RosterEntry> list = mRoster.getEntries();
		List<Contact> contacts = new ArrayList<Contact>(list.size());
		for (RosterEntry entry : list) {
			contacts.add(getContactFromRosterEntry(entry, this));
		}

		return contacts;
	}

	/**
	 * @param entry
	 * @param rm
	 * @return
	 */
	public static final Contact getContactFromRosterEntry(RosterEntry entry,
			RosterManager rm) {
		String user = entry.getUser();
		Contact c = new Contact(user);
		c.setName(entry.getName());
		c.setJID(user);
		Presence p = rm.mRoster.getPresence(user);
		if (p.getStatus() == null || "".equals(p.getStatus())) {
			p.setStatus(rm.mDefaultStatusMessages.get(PresenceStatus
					.getStatusFromPresence(p)));
		}
		c.setStatus(p);
		return c;

	}

	/**
	 * 获得所有分组的名字.
	 * 
	 * @return List<String>
	 */
	public final List<String> getGroupsNames() {
		Collection<RosterGroup> groups = mRoster.getGroups();
		List<String> result = new ArrayList<String>(groups.size());
		for (RosterGroup rosterGroup : groups) {
			result.add(rosterGroup.getName());
		}
		return result;
	}

	/**
	 * 获得所有分组数据
	 * 
	 * @return List<RosterGroup>
	 */
	public final List<RosterGroup> getGroups() {
		Collection<RosterGroup> groups = mRoster.getGroups();
		List<RosterGroup> result = new ArrayList<RosterGroup>(groups.size());
		for (RosterGroup rosterGroup : groups) {
			result.add(rosterGroup);
		}
		return result;
	}

	/**
	 * @return HashMap<String, List<Contact>>
	 */
	public final HashMap<String, List<Contact>> getGropusToHahsMap() {
		HashMap<String, List<Contact>> maps = new HashMap<String, List<Contact>>();
		Collection<RosterGroup> groups = mRoster.getGroups();
		for (RosterGroup rosterGroup : groups) {
			String mNm = rosterGroup.getName();
			Collection<RosterEntry> cts = rosterGroup.getEntries();
			List<Contact> contacts = new ArrayList<Contact>(cts.size());
			for (RosterEntry entry : cts) {
				contacts.add(getContactFromRosterEntry(entry, this));
			}
			maps.put(mNm, contacts);
		}
		return maps;
	}

	/**
	 * 获得指定名字的分组
	 * 
	 * @param groupName
	 * @return
	 */
	public final RosterGroup getGroup(String groupName) {
		return mRoster.getGroup(groupName);
	}

	public final TPresence getPresence(String mJid) {
		return new TPresence(mRoster.getPresence(mJid));
	}

	/**
	 * @param listen
	 */
	public final void addRosterListener(RosterListener listen) {
		if (listen != null) {
			mRemoteRosterListener.add(listen);
		}
	}

	/**
	 * @param listen
	 */
	public final void removeRosterListener(RosterListener listen) {
		if (listen != null) {
			if (mRemoteRosterListener.contains(listen)) {
				mRemoteRosterListener.remove(listen);
			}
		}
	}

	/**
	 * @param mJid
	 * @return
	 */
	public boolean contains(String mJid) {
		if (mRoster.contains(mJid)) {
			return true;
		}
		return false;
	}

	/**
	 * @param JIDKey
	 * @return
	 */
	public final TPresence updataContactPresence(String JIDKey) {
		if (mRoster != null) {
			Presence p = mRoster.getPresence(JIDKey);
			return new TPresence(p);
		} else {
			return null;
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.jivesoftware.smack.RosterListener#entriesAdded(java.util.Collection)
	 */
	@Override
	public void entriesAdded(Collection<String> arg0) {

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.jivesoftware.smack.RosterListener#entriesDeleted(java.util.Collection
	 * )
	 */
	@Override
	public void entriesDeleted(Collection<String> arg0) {

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.jivesoftware.smack.RosterListener#entriesUpdated(java.util.Collection
	 * )
	 */
	@Override
	public void entriesUpdated(Collection<String> arg0) {

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.jivesoftware.smack.RosterListener#presenceChanged(org.jivesoftware
	 * .smack.packet.Presence)
	 */
	@Override
	public void presenceChanged(Presence arg0) {

	}

}
